(function (window, T, util) {
    var object = T.object = {};
    /**
     * 将源对象的所有属性拷贝到目标对象中
     * @author erik
     * @name object.extend
     * @function
     * @grammar object.extend(target, source)
     * @param {Object} target 目标对象
     * @param {Object} source 源对象
     * @see baidu.array.merge
     * @remark
     * 
    1.目标对象中，与源对象key相同的成员将会被覆盖。<br>
    2.源对象的prototype成员不会拷贝。
            
     * @shortcut extend
     * @meta standard
     *             
     * @returns {Object} 目标对象
     */
    object.extend = function (target, source) {
        for (var p in source) {
            if (source.hasOwnProperty(p)) {
                target[p] = source[p];
            }
        }
        
        return target;
    };

    /**
     * 判断一个对象是不是字面量对象，即判断这个对象是不是由{}或者new Object类似方式创建
     * 
     * @name object.isPlain
     * @function
     * @grammar object.isPlain(source)
     * @param {Object} source 需要检查的对象
     * @remark
     * 事实上来说，在Javascript语言中，任何判断都一定会有漏洞，因此本方法只针对一些最常用的情况进行了判断
     *             
     * @returns {Boolean} 检查结果
     */
    object.isPlain  = function(obj){
        var hasOwnProperty = Object.prototype.hasOwnProperty,
            key;
        if ( !obj ||
             //一般的情况，直接用toString判断
             Object.prototype.toString.call(obj) !== "[object Object]" ||
             //IE下，window/document/document.body/HTMLElement/HTMLCollection/NodeList等DOM对象上一个语句为true
             //isPrototypeOf挂在Object.prototype上的，因此所有的字面量都应该会有这个属性
             //对于在window上挂了isPrototypeOf属性的情况，直接忽略不考虑
             !('isPrototypeOf' in obj)
           ) {
            return false;
        }

        //判断new fun()自定义对象的情况
        //constructor不是继承自原型链的
        //并且原型中有isPrototypeOf方法才是Object
        if ( obj.constructor &&
            !hasOwnProperty.call(obj, "constructor") &&
            !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
            return false;
        }
        //判断有继承的情况
        //如果有一项是继承过来的，那么一定不是字面量Object
        //OwnProperty会首先被遍历，为了加速遍历过程，直接看最后一项
        for ( key in obj ) {}
        return key === undefined || hasOwnProperty.call( obj, key );
    };


    /**
     * 对一个object进行深度拷贝
     * 
     * @author berg
     * @name object.clone
     * @function
     * @grammar object.clone(source)
     * @param {Object} source 需要进行拷贝的对象
     * @remark
     * 对于Object来说，只拷贝自身成员，不拷贝prototype成员
     * @meta standard
     *             
     * @returns {Object} 拷贝后的新对象
     */
    object.clone  = function (source) {
        var result = source, i, len;
        if (!source
            || source instanceof Number
            || source instanceof String
            || source instanceof Boolean) {
            return result;
        } else if (util.isArray(source)) {
            result = [];
            var resultLen = 0;
            for (i = 0, len = source.length; i < len; i++) {
                result[resultLen++] = object.clone(source[i]);
            }
        } else if (object.isPlain(source)) {
            result = {};
            for (i in source) {
                if (source.hasOwnProperty(i)) {
                    result[i] = object.clone(source[i]);
                }
            }
        }
        return result;
    };

    /**
     * 遍历Object中所有元素，1.1.1增加
     * @name object.each
     * @function
     * @grammar object.each(source, iterator)
     * @param {Object} source 需要遍历的Object
     * @param {Function} iterator 对每个Object元素进行调用的函数，function (item, key)
     * @version 1.1.1
     *             
     * @returns {Object} 遍历的Object
     */
    object.each = function (source, iterator) {
        var returnValue, key, item; 
        if ('function' == typeof iterator) {
            for (key in source) {
                if (source.hasOwnProperty(key)) {
                    item = source[key];
                    returnValue = iterator.call(source, item, key);
            
                    if (returnValue === false) {
                        break;
                    }
                }
            }
        }
        return source;
    };

    /**
     * shortcut
     */
    T.extend = T.object.extend;
})(window, T, T.util);